home *** CD-ROM | disk | FTP | other *** search
- #include "bgi_font.h"
-
- #include <string.h>
- #include <fcntl.h>
- #include <io.h>
- #include <STDDEF.H>
- #include <alloc.h>
-
- #define MAXFILESIZE 16000
-
- char* BGI_Font::buffer = NULL;
-
- BGI_Font::BGI_Font(char* fileName)
- {
- h_just = 0; // LEFT_TEXT
- v_just = 0; // BOTTOM_TEXT
- if(buffer != NULL)
- {
- delete buffer;
- buffer = NULL;
- }
- multx = multy = divx = divy = 1;
- polypoints = NULL;
- if(fileName == NULL)
- return;
- load(fileName);
- polypoints = new int[256]; // Default number of points in closed
- };
- //////////////
- BGI_Font::~BGI_Font()
- {
- delete[] buffer;
- buffer = NULL;
- delete polypoints;
- }
- ////////////////
- void BGI_Font::load(char* fileName)
- {
- int handle;
- if((handle = open(fileName, O_RDONLY | O_BINARY)) == -1)
- {
- kh_error_code = KH_FILE_ERROR;
- return;
- }
- if(buffer == NULL)
- if((buffer = new char[MAXFILESIZE]) == NULL)
- {
- close(handle);
- kh_error_code = KH_MEMORY_ERROR;
- return;
- }
-
- if(read(handle, buffer, MAXFILESIZE) == -1)
- {
- delete buffer;
- close(handle);
- kh_error_code = KH_FILE_ERROR;
- return;
- }
- close(handle);
-
- int pos = 0;
- while(buffer[pos] != 26) // All info fields are skipped
- pos++;
- pos++;
- // BGI_Font Font Info
- HeaderSize = ((int*)(buffer + pos))[0]; // ...
- pos += sizeof(int);
- pos += 4; // char* FontName;
- FontSize = ((int*)(buffer + pos))[0]; // ...
- pos += sizeof(int); // int FontSize, Font without header
- pos++; // char FontVersion, > 0
- pos++; // char FontModification;
- pos += sizeof(int); // int BGI_FontInfo, BGI_Font version
- // BGI_Font Font descriptor
- while(buffer[pos] != '+')
- pos++; // char DscSignature, Always '+'
- pos++;
- SymbolsInFont = buffer[pos++]; // Usually start from ' '
- pos++; pos++;
- FirstSymbol = buffer[pos++]; // Usually start from ' '
- StrokesOffset = ((int*)(buffer + pos))[0]; // Characters descriptions offset
- pos += sizeof(int);
- FillFlag = buffer[pos++]; // Fill or not, default 0
- CapitalHeight = buffer[pos++]; // ...
- BaseLine = buffer[pos++]; // Usually 0
- Descender = buffer[pos++]; // for y, g and other
- pos += 5; // char Stub02[5], Not used and set to 0
-
- // BGI_Font Tables
- OffsetTable = (int*)(buffer + pos); // Offsets of symbols descriptions
- pos += SymbolsInFont * 2;
- WidthTable = (buffer + pos);
- pos += SymbolsInFont;
- vectors = buffer + pos;
- }
- ////////////////
- int BGI_Font::draw_char(int x, int y, uchar c, int dir)
- {
- if(c >= SymbolsInFont + FirstSymbol || c < FirstSymbol) // ERROR !!!
- { // Out of inter-
- kh_error_code = KH_BGI_ERROR; // val
- return 0;
- }
- char* pos = vectors + OffsetTable[c - FirstSymbol]; // Find description
- int numpoint = 0;
- moveto(x, y);
- int xpos; int sign; int ypos;
-
- for(int i = 0; (pos [i] & 128); i += 2) // While end of char
- { // description
- if(!dir)
- {
- xpos = x + (pos [i] & 127) * multx / divx; // Calculate coords.
- sign = pos[i + 1] & 64 ? 1 : 0;
- ypos = y + (sign * 64 - (pos [i + 1] & 63)) * multy / divy;
- }
- else
- {
- sign = pos[i + 1] & 64 ? 1 : 0;
- xpos = x + (sign * 64 - (pos [i + 1] & 63)) * multx / divx; // Calculate coords.
- ypos = y - (pos [i] & 127) * multy / divy;
- }
- if((pos [i + 1] & 128) && (pos [i] & 128)) // Drawing via moveto
- { // and lineto
- if(FillFlag) // For filled fonts lineto
- { // draws filled part of
- polypoints[numpoint++] = xpos; // character, like upper
- polypoints[numpoint++] = ypos; // '.' in ':'
- } // Moveto begin next part
- else // of char.
- lineto(xpos, ypos);
- }
- else
- {
- if(FillFlag && numpoint)
- {
- numpoint = numpoint / 2;
- fillpoly(numpoint, polypoints);
- numpoint = 0;
- }
- else
- moveto(xpos, ypos);
- }
- }
- if(FillFlag && numpoint) // If next part of char was not
- { // shown.
- numpoint = numpoint / 2;
- fillpoly(numpoint, polypoints);
- numpoint = 0;
- }
-
- return (int)((long)WidthTable[c - FirstSymbol] * multx / divx);
- }
- ////////////////
- int BGI_Font::outtextxy(int x, int y, uchar far* str, int dir)
- {
- int len = 0;
- int i = 0;
- int w;
- int h = v_just * getheight() / 2;
- while(str[i])
- switch(h_just)
- {
- case 1: w = gettextwidth(str);
- if(!dir)
- len += draw_char(x - w/2 + len, y + h, str[i++]);
- else
- len += draw_char(x + h, y + w/2 - len, str[i++], dir);
- break;
- case 2: w = gettextwidth(str);
- if(!dir)
- len += draw_char(x - w + len, y + h, str[i++]);
- else
- len += draw_char(x + h, y + w - len, str[i++], dir);
- break;
- case 0:
- default:
- if(!dir)
- len += draw_char(x + len, y + h, str[i++]);
- else
- len += draw_char(x + h, y - len, str[i++], dir);
- break;
- }
- return len;
- }
- ////////////////////
- int BGI_Font::gettextwidth(uchar far* str)
- {
- int len = 0;
- int i = 0;
- while(str[i])
- {
- len += WidthTable[str[i] - FirstSymbol];
- i++;
- }
- return len;
- }
-
- /*
- // Demo for BGI, DOS, Draw nothing, using ABS_GRAF functions.
- // See BGIPAINT for the working example.
- void main()
- {
- int gdriver = DETECT, gmode;
- initgraph(&gdriver, &gmode, "");
- BGI_Font bgi("bold.chr");
- setcolor(LIGHTGREEN);
- bgi.draw_char(100, 200, 'J', 1);
- bgi.draw_char(100, 200, 'J', 0);
- for(int c = 0; c < 255; c++)
- {
- setfillstyle(SOLID_FILL, RED);
- bar(0,0,getmaxx(),getmaxy());
- setfillstyle(SOLID_FILL, BLUE);
- bgi.setusercharsize(1,1,1,1);
- bgi.draw_char(50, 300, c);
- bgi.setusercharsize(2,1,2,1);
- bgi.draw_char(150, 300, c);
- bgi.setusercharsize(3,1,5,1);
- bgi.draw_char(300, 300, c);
- bgi.setusercharsize(5,1,5,2);
- bgi.draw_char(500, 300, c);
- }
-
- closegraph();
- }
- */